﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BacteriaSimulation.Simulation
{
    public class UpdateBacteriumPositionTask : AbstractTask
    {
        public override TaskOutcome executeTask(Simulation simulation, Bacterium bacterium, SimulationEnvironment env)
        {
            double period = simulation.SimulationPeriodSec;

            //computes the shift given by the current speed vector
            double shiftX = bacterium.Speed.XComponent * period;
            double shiftY = bacterium.Speed.YComponent * period;
            Vector2D shift1 = new Vector2D(shiftX, shiftY);

            //new 
            //Vector2D composedAccelerationVector = new Vector2D(bacterium.AccelerationMagnitude * bacterium.AccelerationDirection.XComponent,
            //    bacterium.AccelerationMagnitude * bacterium.AccelerationDirection.YComponent);
            //if (env.ActiveForceField != null)
            //{
            //    Vector2D fieldAcceleration = GetForceFieldAcceleration(env.ActiveForceField, bacterium);
            //    composedAccelerationVector.XComponent += fieldAcceleration.XComponent;
            //    composedAccelerationVector.YComponent += fieldAcceleration.YComponent;
            //}
            //double speedIncrementXComp = composedAccelerationVector.XComponent * period;
            //double speedIncrementYComp = composedAccelerationVector.YComponent * period;
            //end new

            /* //old * */
            // Computes the shift due to the current acceleration
            UnitVector2D directionVect = bacterium.AccelerationDirection;
            Double speedIncrementMagnitude = bacterium.AccelerationMagnitude * period;
            // the speed components along the direction of the acceleration
            double speedIncrementXComp = speedIncrementMagnitude * directionVect.XComponent;
            double speedIncrementYComp = speedIncrementMagnitude * directionVect.YComponent;
            /* */
            double shiftIncrementXComp = .5 * speedIncrementXComp * period;
            double shiftIncrementYComp = .5 * speedIncrementYComp * period;

            //Vector2D speedIncrementVector = new Vector2D(speedIncrementXComp, speedIncrementYComp);
            Vector2D resultingSpeedVector = new Vector2D(speedIncrementXComp + bacterium.Speed.XComponent,
                speedIncrementYComp + bacterium.Speed.YComponent);

            resultingSpeedVector = Vector2D.normalizeToMagnitude(resultingSpeedVector, bacterium.SpeedMagnitude);

            Vector2D resultingShiftVector = new Vector2D(shiftX + shiftIncrementXComp,
                shiftY + shiftIncrementYComp);

            bacterium.Speed = resultingSpeedVector;
            bacterium.X += resultingShiftVector.XComponent;
            bacterium.Y += resultingShiftVector.YComponent;

            return new TaskOutcome(TaskOutcomeType.CONTINUE);
        }

        //private Vector2D GetForceFieldAcceleration(ForceField forceField, Bacterium bacterium)
        //{
        //    Vector2D forceVector = forceField.GetAppliedField(bacterium.Position);
        //    if (forceVector.XComponent == 0 && forceVector.YComponent == 0)
        //    {
        //        return new Vector2D(0, 0);
        //    }
        //    double forceMagnitude = forceVector.GetMagnitude();
        //    // Assuming mass == Energy an applying F = m*a
        //    double accelerationMagnitude = forceMagnitude / bacterium.Energy;
        //    UnitVector2D forceDirection = new UnitVector2D(forceVector.XComponent, forceVector.YComponent);
        //    Vector2D accelerationVector = new Vector2D(accelerationMagnitude * forceDirection.XComponent, accelerationMagnitude * forceDirection.YComponent);
        //    return accelerationVector;
        //}
    }
}
